﻿using System;
using System.Collections;
using System.Xml;
using InfoJetSoft.Service.Entity;

namespace InfoJetSoft.Service.Util
{
	
	class NamespaceUtil
	{
		
		public static string toFullName(string prefix, string baseName)
		{
			if (prefix == null || prefix.Length <= 0)
			{
				return baseName;
			}
			else
			{
				return prefix + ":" + baseName;
			}
		}

		public static string getLocalName( string qname )
		{
			int index = qname.IndexOf( ":" );
			if( index >= 0 )
			{
				return qname.Substring( index + 1 );
			}
			else
			{
				return qname;
			}
		}

		public static string getPrefix( string qname )
		{
			int index = qname.IndexOf( ":" );
			if( index >= 0 )
			{
				return qname.Substring( 0, index );
			}
			else
			{
				return "";
			}
		}

		//将XmlDocument中的namespace和Manifest中的统一.
		public static void unifyNamespaces( XmlDocument doc, Manifest manifest )
		{
			//找出所有Xmlns属性.
			ArrayList xmlnsAttrList = new ArrayList();
			foreach( XmlAttribute attr in doc.DocumentElement.Attributes )
			{
				if( attr.NamespaceURI != null && attr.NamespaceURI.Equals( JetConstant.URI_XMLNS ) )
				{
					xmlnsAttrList.Add( attr );
				}
			}
			//遍历Xmlns属性.
			foreach( XmlAttribute attr in xmlnsAttrList )
			{
				//找到manifest中的同uri的prefix.
				string manifestPrefix = findXmlnsAttr( manifest.Doc, attr.Value );
				if( manifestPrefix != null && (!manifestPrefix.Equals(attr.LocalName)) )
				{
					//和manifest中的prefix不同,删除旧的添加一个和manifest中namespace前缀一致的attr.
					doc.DocumentElement.RemoveAttributeNode( attr );
					XmlAttribute unifiedAttr = doc.CreateAttribute( "xmlns", manifestPrefix, JetConstant.URI_XMLNS );
					unifiedAttr.Value = attr.Value;
					doc.DocumentElement.SetAttributeNode( unifiedAttr );
					//修改属于同一namespace的所有结点前缀.
					XmlNodeList nodeList = doc.SelectNodes( "//*[namespace-uri()='" + attr.Value + "']" );
					//这里的//*只能选出所有的元素,但是试验表明,只要修改元素的prefix,其内部的属性(设置是隔层的)的prefix也自动被修改.
					foreach( XmlNode node in nodeList )
					{
						node.Prefix = manifestPrefix;
					}
				}
			}
		}

		private static string findXmlnsAttr( XmlDocument doc, string uri )
		{
			foreach( XmlAttribute attr in doc.DocumentElement.Attributes )
			{
				if( attr.NamespaceURI != null && attr.NamespaceURI.Equals( JetConstant.URI_XMLNS ) )
				{
					if( attr.Value.Equals( uri ) )
					{
						return attr.LocalName;
					}
				}
			}
			return null;
		}

	}
}